package com.ruoyi.base.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.ruoyi.base.SnakerEngineFacets;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SnowFlakeUtils;
import com.ruoyi.common.utils.SecurityUtils;
import org.apache.commons.lang.StringUtils;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.*;
import org.snaker.engine.entity.Process;
import org.snaker.engine.model.TaskModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.base.mapper.BaseProcessMapper;
import com.ruoyi.base.domain.BaseProcess;
import com.ruoyi.base.service.IBaseProcessService;
import org.springframework.ui.Model;

/**
 * Snaker流程Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-10-17
 */
@Service
@Transactional
public class BaseProcessServiceImpl implements IBaseProcessService 
{
    @Autowired
    private BaseProcessMapper baseProcessMapper;

    @Autowired
    private SnakerEngineFacets snakerEngineFacets;

    /**
     * 查询Snaker流程
     * 
     * @param id Snaker流程主键
     * @return Snaker流程
     */
    @Override
    public BaseProcess selectBaseProcessById(Long id)
    {
        return baseProcessMapper.selectBaseProcessById(id);
    }

    /**
     * 查询Snaker流程列表
     * 
     * @param baseProcess Snaker流程
     * @return Snaker流程
     */
    @Override
    public List<BaseProcess> selectBaseProcessList(BaseProcess baseProcess)
    {
        return baseProcessMapper.selectBaseProcessList(baseProcess);
    }

    /**
     * 新增Snaker流程
     * 
     * @param baseProcess Snaker流程
     * @return 结果
     */
    @Override
    public int insertBaseProcess(BaseProcess baseProcess)
    {
        if(baseProcess.getId()==null){
        baseProcess.setId(SnowFlakeUtils.snowFlakeId());
    }
        baseProcess.setCreateUserId(SecurityUtils.getUserId());
        baseProcess.setCreateUserName(SecurityUtils.getUserNickName());
        baseProcess.setCreateTime(DateUtils.getNowDate());
        return baseProcessMapper.insertBaseProcess(baseProcess);
    }

    /**
     * 修改Snaker流程
     * 
     * @param baseProcess Snaker流程
     * @return 结果
     */
    @Override
    public int updateBaseProcess(BaseProcess baseProcess)
    {
        baseProcess.setUpdateUserId(SecurityUtils.getUserId());
        baseProcess.setUpdateUserName(SecurityUtils.getUserNickName());
        baseProcess.setUpdateTime(DateUtils.getNowDate());
        return baseProcessMapper.updateBaseProcess(baseProcess);
    }

    /**
     * 批量删除Snaker流程
     * 
     * @param ids 需要删除的Snaker流程主键
     * @return 结果
     */
    @Override
    public int deleteBaseProcessByIds(Long[] ids)
    {
        return baseProcessMapper.deleteBaseProcessByIds(ids);
    }

    /**
     * 删除Snaker流程信息
     * 
     * @param id Snaker流程主键
     * @return 结果
     */
    @Override
    public int deleteBaseProcessById(Long id)
    {
        return baseProcessMapper.deleteBaseProcessById(id);
    }

    /**
     * 批量---逻辑删除
     *
     * @param ids 需要删除的Snaker流程ID
     * @return 结果
     */
    @Override
    public int setDeleteByIds(Long[] ids)
    {
        Long userId = SecurityUtils.getUserId();
        String userNickName = SecurityUtils.getUserNickName();
        return baseProcessMapper.setDeleteByIds(ids,userId,userNickName);
    }

    /**
     * 删除---逻辑删除
     *
     * @param id Snaker流程ID
     * @return 结果
     */
    @Override
    public int setDeleteById(Long id)
    {
        Long userId = SecurityUtils.getUserId();
        String userNickName = SecurityUtils.getUserNickName();
        return baseProcessMapper.setDeleteById(id,userId,userNickName);
    }

    /**
     * 发布流程
     * @param id
     * @return
     */
    public int processPublish(Long id){
        BaseProcess baseProcess = selectBaseProcessById(id);
        if(baseProcess==null){
            throw new GlobalException("流程不存在");
        }
        // 判断是否存在,存在则重新发布(在wf_process中不会生成新的记录,会影响已运行的实例)
//        if(StringUtils.isNotBlank(baseProcess.getWfProcessId())){
//            snakerEngineFacets.redeploy(baseProcess.getWfProcessId(),baseProcess.getWfProcessContent());
//        }else{
//            String deploy = snakerEngineFacets.deploy(baseProcess.getWfProcessContent());
//            baseProcess.setWfProcessId(deploy);
//        }
        // 直接发布--在wf_process中生成新的记录(不会影响已运行的实例)
        String deploy = snakerEngineFacets.deploy(baseProcess.getWfProcessContent());
        baseProcess.setWfProcessId(deploy);
        updateBaseProcess(baseProcess);
        return 1;
    }
    /**
     * 发起流程
     * @param id
     * @return
     */
    public Order processStart(Long id, Map<String,Object> params){
        BaseProcess baseProcess = selectBaseProcessById(id);
        if(baseProcess==null){
            throw new GlobalException("流程不存在");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Order order = snakerEngineFacets.startAndExecute(baseProcess.getWfProcessId(), loginUser.getUsername(), params);
        return order;
    }

    /**
     * 所有流程的实例查询
     * @param page
     */
    public void getOrderList(Page<HistoryOrder> page){
        snakerEngineFacets.getEngine().query().getHistoryOrders(page, new QueryFilter());
    }
    /**
     * 查询当前用户完成的任务
     * @return
     */
    public void getUserHistoryTasks(Page<HistoryTask> page){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        snakerEngineFacets.getEngine().query().getHistoryTasks(page,new QueryFilter().setOperator(loginUser.getUsername()));
    }
    /**
     * 查询实例的已完成任务
     * @param orderId
     * @return
     */
    public List<HistoryTask> getHistoryTasks(String orderId){
        List<HistoryTask> tasks = snakerEngineFacets.getEngine().query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
        return tasks;
    }

    /**
     * 查询实例正在进行的任务
     * @param orderId
     * @return
     */
    public List<Task> getActiveTasks(String orderId){
        List<Task> tasks = null;
        if(StringUtils.isNotEmpty(orderId)) {
            tasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(orderId));
        }
        return tasks;
    }

    /**
     * 查询用户待办任务
     * @param page
     */
    public void getUserTask(Page<WorkItem> page){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        snakerEngineFacets.getEngine().query().getWorkItems(page,
                new QueryFilter().setOperator(loginUser.getUsername()));
    }

    /**
     * 给实例的指定任务节点添加操作人
     * @param orderId
     * @param taskName
     * @param operator
     */
    public void addTaskActor(String orderId, String taskName, String operator) {
        List<Task> tasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(orderId));
        for(Task task : tasks) {
            if(task.getTaskName().equalsIgnoreCase(taskName) && StringUtils.isNotEmpty(operator)) {
                snakerEngineFacets.getEngine().task().addTaskActor(task.getId(), operator);
            }
        }
    }

    /**
     * 查询实例,指定任务的操作人信息
     * @param orderId
     * @param taskName
     * @return
     */
    public List<String> getTaskActor(String orderId, String taskName){
        List<String> taskActors = new ArrayList<>();
        List<Task> tasks = snakerEngineFacets.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(orderId));
        for(Task task : tasks) {
            if(task.getTaskName().equalsIgnoreCase(taskName)) {
                String[] actors = snakerEngineFacets.getEngine().query().getTaskActorsByTaskId(task.getId());
                taskActors = Arrays.asList(actors);
            }
        }
        return taskActors;
    }

    /**
     * 查询流程定义信息
     * @param processId
     * @return
     */
    public Process getProcessById(String processId){
        Process processById = snakerEngineFacets.getEngine().process().getProcessById(processId);
        return processById;
    }

    /**
     * 查询流程的所有节点信息
     * @param processId
     * @return
     */
    public List<TaskModel> getProcessNodes(String processId){
        Process process = snakerEngineFacets.getEngine().process().getProcessById(processId);
        List<TaskModel> models = process.getModel().getModels(TaskModel.class);
        List<TaskModel> viewModels = new ArrayList<TaskModel>();
        for(TaskModel model : models) {
            TaskModel viewModel = new TaskModel();
            viewModel.setName(model.getName());
            viewModel.setDisplayName(model.getDisplayName());
            viewModel.setForm(model.getForm());
            viewModels.add(viewModel);
        }
        return viewModels;
    }
}
